package com.example.springresource02.demo;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author hu wenhao
 * @version 1.0.0
 * @description
 * @date 2022/6/1 15:44
 */
public class TestBeanFactory {


    public static void main(String[] args) {
        AbstractBeanDefinition beanDefinition =
                BeanDefinitionBuilder.genericBeanDefinition(Config.class)
                        .setScope("singleton")
                        .getBeanDefinition();
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

        factory.registerBeanDefinition("config",beanDefinition);

        for (String definitionName : factory.getBeanDefinitionNames()) {
            System.out.println("definitionName = " + definitionName);
        }

        System.out.println("-----------------------------");
        //调用注解配置工具类，给BeanFactory添加一些后处理器。
        AnnotationConfigUtils.registerAnnotationConfigProcessors(factory);

        //拿到所有Bean工厂后处理器
        factory.getBeansOfType(BeanFactoryPostProcessor.class).values()
                .forEach(beanFactoryPostProcessor -> beanFactoryPostProcessor.postProcessBeanFactory(factory));

        //Bean后处理器，针对bean的生命周期的各个阶段提供扩展，例如解析@AutoWire @Resource注解的后处理器
        factory.getBeansOfType(BeanPostProcessor.class).values().forEach(factory::addBeanPostProcessor);

        for (String definitionName : factory.getBeanDefinitionNames()) {
            System.out.println("definitionName = " + definitionName);
        }

        System.out.println("factory.getBean(Bean1.class).getBean2() = " + factory.getBean(Bean1.class).getBean2());
    }

    @Configuration
    static class Config{

        @Bean
        public Bean1 bean1() {return new Bean1();}

        @Bean
        public Bean2 bean2() {return new Bean2();}
    }


    static class Bean1{
        public Bean1(){
            System.out.println("构造Bean1");
        }

        @Autowired
        private Bean2 bean2;

        public Bean2 getBean2(){return bean2;}

        public void setBean2(Bean2 bean2) {
            this.bean2 = bean2;
        }
    }

    static class Bean2{

        public Bean2(){
            System.out.println("构造Bean2");
        }

    }
}
